package cs.android.viewbase;

import java.lang.ref.SoftReference;

import static cs.java.lang.Lang.is;
import static cs.java.lang.Lang.map;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.ViewAnimator;
import cs.android.HasContext;
import cs.android.rpc.BitmapRequest;
import cs.android.view.ImageViewPresenter;
import cs.java.collections.Map;
import cs.java.event.Task;

public class ViewPresenterImpl extends ContextPresenter implements ViewPresenter {

	private View view;

	private static Map<String, SoftReference<Bitmap>> bitmapcache = map();

	ViewPresenterImpl() {}

	ViewPresenterImpl(HasContext hascontext) {
		super(hascontext);
	}

	public ViewPresenterImpl(HasContext hascontext, int layoutId) {
		this(hascontext);
		setInflateView(layoutId);
	}

	public ViewPresenterImpl(int layoutId) {
		setInflateView(layoutId);
	}

	public ViewPresenterImpl(final View view) {
		super(view.getContext());
		this.view = view;
	}

	public ViewPresenterImpl(final View parent, int layoutId) {
		super(new HasContext() {
			public Context getContext() {
				return parent.getContext();
			}
		});
		setInflateView(layoutId);
	}

	protected Display getDisplay() {
		return ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE))
				.getDefaultDisplay();
	}

	protected View getView() {
		return view;
	}

	protected void hide(int viewId) {
		hide(getView(viewId));
	}

	protected void hide(View view) {
		view.setVisibility(View.GONE);
	}

	protected void hideSoftInput(int flag) {
		InputMethodManager in = (InputMethodManager) getService(Context.INPUT_METHOD_SERVICE);
		in.hideSoftInputFromWindow(asView().getWindowToken(), flag);
	}

	protected void hideView(int... viewIds) {
		for (int id : viewIds)
			hide(getView(id));
	}

	protected View inflateLayout(int layout_id) {
		LayoutInflater inflater = (LayoutInflater) getService(Context.LAYOUT_INFLATER_SERVICE);
		return inflater.inflate(layout_id, null);
	}

	protected boolean isChecked(int id) {
		return getCompoundButton(id).isChecked();
	}

	protected boolean isVisible(int id) {
		return isVisible(getView(id));
	}

	protected boolean isVisible(View view) {
		return view.getVisibility() == View.VISIBLE;
	}

	protected void loadImage(final ImageView imageView, final BitmapRequest request,
			final String imageId) {
		SoftReference<Bitmap> bitmapReference = bitmapcache.value(imageId);
		if (is(bitmapReference) && is(bitmapReference.get())) {
			request.stop();
			imageView.setImageBitmap(bitmapReference.get());
		} else new Task(this, request.getOnLoaded()) {
			public void run() {
				Bitmap bitmap = request.getBitmap();
				bitmapcache.put(imageId, new SoftReference<Bitmap>(bitmap));
				imageView.setImageBitmap(bitmap);
			}
		};
	}

	protected void loadImage(int imageViewId, BitmapRequest request, String imageId) {
		loadImage(getImageView(imageViewId), request, imageId);
	}

	protected void setChecked(int id, boolean checked) {
		getCompoundButton(id).setChecked(checked);
	}

	protected void setImageViewResource(int viewId, int drawable) {
		getImageView(viewId).setImageResource(drawable);
	}

	protected void setInflateView(int layoutId) {
		view = inflateLayout(layoutId);
	}

	protected void setOnCheckedChangeListener(int id, OnCheckedChangeListener listener) {
		getCompoundButton(id).setOnCheckedChangeListener(listener);
	}

	protected void setViewVisible(int viewId, boolean visible) {
		if (visible) showView(viewId);
		else hideView(viewId);
	}

	protected void setVisible(int viewId, boolean visible) {
		if (visible) getView(viewId).setVisibility(View.VISIBLE);
		else getView(viewId).setVisibility(View.GONE);
	}

	protected void show(View view) {
		view.setVisibility(View.VISIBLE);
	}

	protected void showView(int... viewIds) {
		for (int id : viewIds)
			show(getView(id));
	}

	public ListView asListView() {
		return (ListView) asView();
	}

	public ProgressBar asProgressBar() {
		return (ProgressBar) asView();
	}

	public View asView() {
		return view;
	}

	public Button getButton(int id) {
		return (Button) getView(id);
	}

	public CheckBox getCheckBox(int id) {
		return (CheckBox) getView(id);
	}

	public CompoundButton getCompoundButton(int id) {
		return (CompoundButton) getView(id);
	}

	public DatePicker getDatePicker(int id) {
		return (DatePicker) getView(id);
	}

	public EditText getEditText(int id) {
		return (EditText) getView(id);
	}

	public FrameLayout getFrameLayout(int id) {
		return (FrameLayout) getView(id);
	}

	public ImageView getImageView(int id) {
		return (ImageView) getView(id);
	}

	public LinearLayout getLinearLayout(int id) {
		return (LinearLayout) getView(id);
	}

	public ListView getListView(int id) {
		return (ListView) getView(id);
	}

	public RadioButton getRadioButton(int id) {
		return (RadioButton) getView(id);
	}

	public RadioGroup getRadioGroup(int id) {
		return (RadioGroup) getView(id);
	}

	public ScrollView getScrollView(int id) {
		return (ScrollView) getView(id);
	}

	public String getTextValue(int id) {
		if (is(getTextView(id))) return getTextView(id).getText().toString();
		return null;
	}

	public TextView getTextView(int id) {
		return (TextView) getView(id);
	}

	public ToggleButton getToggleButton(int id) {
		return (ToggleButton) getView(id);
	}

	public View getView(int id) {
		return asView().findViewById(id);
	}

	public ViewAnimator getViewAnimator(int id) {
		return (ViewAnimator) getView(id);
	}

	public ViewGroup getViewGroup(int id) {
		return (ViewGroup) getView(id);
	}

	public int getWidth() {
		return asView().getWidth();
	}

	public void hide() {
		hide(asView());
	}

	public boolean isVisible() {
		return asView().getVisibility() == View.VISIBLE;
	}

	public void setButtonText(int viewId, int text) {
		getButton(viewId).setText(text);
	}

	public void setButtonText(int viewId, String text) {
		getButton(viewId).setText(text);
	}

	public void setImageValue(int imageViewId, int imageResource) {
		getImageView(imageViewId).setImageResource(imageResource);
	}

	public void setImageValue(int imageViewId, String imageUrl) {
		new ImageViewPresenter(getImageView(imageViewId), imageUrl);
	}

	public void setOnClickListener(int id, OnClickListener onClickListener) {
		getView(id).setOnClickListener(onClickListener);
	}

	public void setOnClickListener(OnClickListener onClickListener) {
		asView().setOnClickListener(onClickListener);
	}

	public void setPercentWidth(int viewId, int percent, int minimal, int maximal) {
		double onePercent = getDisplay().getWidth() / 100;
		int wantedSize = (int) (onePercent * percent);
		if (wantedSize < minimal) wantedSize = minimal;
		else if (wantedSize > maximal) wantedSize = maximal;
		getView(viewId).setLayoutParams(
				new FrameLayout.LayoutParams(wantedSize, getView(viewId).getLayoutParams().height));
	}

	public void setTextValue(int viewId, int stringId) {
		getTextView(viewId).setText(getString(stringId));
	}

	public void setTextValue(int viewId, int stringId, Object... args) {
		getTextView(viewId).setText(getString(stringId, args));
	}

	public void setTextValue(int viewId, String text) {
		getTextView(viewId).setText(text);
	}

	public void setView(View view) {
		this.view = view;
	}

	public void show() {
		show(asView());
	}

}
